package com.yueyang.sojourn.server.service.sojourn.banner;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yueyang.sojourn.server.model.enums.BannerShowTypeEnum;
import com.yueyang.sojourn.server.model.enums.JumpTypeEnum;
import com.yueyang.sojourn.server.model.enums.OperStatusEnum;
import com.yueyang.sojourn.server.model.enums.ShelfStatusEnum;
import com.yueyang.sojourn.server.model.po.SojournBanner;
import com.yueyang.sojourn.server.model.po.SojournMerch;
import com.yueyang.sojourn.server.model.po.SojournProject;
import com.yueyang.sojourn.server.model.vo.SojournBannerVo;
import com.yueyang.sojourn.server.service.attachdetail.AttachDetailService;
import com.yueyang.sojourn.server.service.sojourn.merch.SojournMerchService;
import com.yueyang.sojourn.server.service.sojourn.project.SojournProjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author yemingxing
 * @summary
 * @Copyright (c) 2020, Yueyang Group All Rights Reserved.
 * @since 2020-02-27 00:59
 */
@Service
@Slf4j
public class ReadBannerService {

    @Autowired
    private SojournBannerService sojournBannerService;

    @Autowired
    private AttachDetailService attachDetailService;

    @Autowired
    private SojournMerchService sojournMerchService;

    @Autowired
    private SojournProjectService sojournProjectService;

    /**
     * 允许的最大展位数
     */
    private final int position = 5;

    /**
     * 判断该时段有无剩余展位
     *
     * @param showTimeBegin
     * @param showTimeEnd
     * @return boolean
     */
    public boolean positionAvailable(Date showTimeBegin, Date showTimeEnd, List<Long> excludeIds) {
        // 结束时间晚于showTimeBegin 且 开始时间早于showTimeEnd
        List<SojournBanner> banners = sojournBannerService.selectList(null, null, null, showTimeEnd, showTimeBegin, null, null, excludeIds);
        return banners == null || banners.size() < position;
    }

    /**
     * 排序值是否重复
     *
     * @param sort
     * @return boolean
     */
    public boolean sortAvailable(int sort) {
        return sojournBannerService.selectExistsSort(sort, new Date(), null) == null;
    }

    /**
     * 排序值是否重复
     *
     * @param sort
     * @return boolean
     */
    public boolean sortAvailable(int sort, Date showTimeBegin, Date showTimeEnd) {
        // 结束时间晚于showTimeBegin 且 开始时间早于showTimeEnd
        return sojournBannerService.selectExistsSort(sort, showTimeBegin, showTimeEnd) == null;
    }

    /**
     * 列表分页查询
     *
     * @param keyWord
     * @param showType
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PageInfo<SojournBannerVo> page(String keyWord, Integer showType, int pageNo, int pageSize) {
        try {
            PageInfo<SojournBanner> pageInfo = PageHelper.startPage(pageNo, pageSize).setOrderBy("show_time_begin desc").doSelectPageInfo(() -> {
                sojournBannerService.selectList(keyWord, showType, null, null, null, null, null, null);
            });
            PageInfo<SojournBannerVo> voPageInfo = new PageInfo<>();
            BeanUtils.copyProperties(pageInfo, voPageInfo);
            voPageInfo.setList(pageInfo.getList().parallelStream()
                    .map(sojournBanner -> po2vo(sojournBanner, false))
                    .collect(Collectors.toList()));
            return voPageInfo;
        } finally {
            PageHelper.clearPage();
        }
    }

    public SojournBannerVo findVoById(long bannerId) {
        SojournBanner sojournBanner = sojournBannerService.selectByPrimaryKey(bannerId);
        return po2vo(sojournBanner, false);
    }

    private SojournBannerVo po2vo(SojournBanner sojournBanner, boolean fromWeixin) {
        SojournBannerVo bannerVo = new SojournBannerVo();
        BeanUtils.copyProperties(sojournBanner, bannerVo);
        bannerVo.setAttachDetail(attachDetailService.selectByPrimaryKey(sojournBanner.getAttachId()));
        Date now = new Date();
        // 展示状态是一个实时状态，数据库中没有记录该字段
        if (bannerVo.getShowTimeBegin().after(now)) {
            bannerVo.setBannerShowType(BannerShowTypeEnum.TO_BE_SHOW.getCode());
        } else if (bannerVo.getShowTimeEnd().after(now)) {
            bannerVo.setBannerShowType(BannerShowTypeEnum.SHOWING.getCode());
        } else {
            bannerVo.setBannerShowType(BannerShowTypeEnum.OFF.getCode());
        }
        if (fromWeixin && JumpTypeEnum.MERCH.getCode() == sojournBanner.getJumpType()) {
            try {
                SojournMerch sojournMerch = sojournMerchService.selectByPrimaryKey(Long.valueOf(sojournBanner.getJumpVal()));
                if (sojournMerch.getShelfStatus() != ShelfStatusEnum.BEING_ON.getCode()) {
                    return null;
                }
            } catch (NumberFormatException e) {
                log.error("banner 跳转-商品id异常：" + sojournBanner.getJumpVal(), e);
            }
        }
        if (fromWeixin && JumpTypeEnum.PROJECT.getCode() == sojournBanner.getJumpType()) {
            try {
                SojournProject sojournProject = sojournProjectService.selectByPrimaryKey(Long.valueOf(sojournBanner.getJumpVal()));
                if (sojournProject.getOperStatus() != OperStatusEnum.OPENING.getCode()) {
                    return null;
                }
            } catch (NumberFormatException e) {
                log.error("banner 跳转-项目id异常：" + sojournBanner.getJumpVal(), e);
            }
        }
        return bannerVo;
    }

    public List<SojournBannerVo> findShowingBanner(boolean fromWeixin) {
        PageInfo<SojournBanner> pageInfo = PageHelper.startPage(1, position, false)
                .setOrderBy("sort desc").doSelectPageInfo(() ->
                        sojournBannerService.selectList(null, BannerShowTypeEnum.SHOWING.getCode(), null, null, null, null, null, null));
        return pageInfo.getList().parallelStream().map(sojournBanner -> this.po2vo(sojournBanner, fromWeixin)).filter(Objects::nonNull).collect(Collectors.toList());
    }
}
